var MAP_NAV_URI = "/livcos.org/Map/web/nav.html";

BasePath.setByDoc(document, MAP_NAV_URI);

E.Config.get("EditMode").suppressToggle = true;
E.Config.get("EditMode").suppressTemplatePanel = true;

// the visual select should be more grid like...
E.Config.get("SelectionSupport").hFactor = 1;
E.Config.get("SelectionSupport").vFactor = 1;

scriptSupport.addInit(function() {
	DeleteAction.jobUri = MAP_EDIT_JOB;
	ClipboardAction.jobUri = MAP_EDIT_CLIPBOARD_JOB;

	var doc = Doc();
	doc.navLayout = new NavLayout(doc);
	
	// remember the current item (following add-link actions will relate to this
	// item)
	var c = new Cookie("map_item");
	c.setValue(doc.navLayout.mainItem.element.id);

	new EventListener(document, "keydown", function(evn) {
		var doc = Doc(this);
		if (evn.keyCode == 45) { // insert
			var a = new ShowInsertAction(doc.navLayout.mainItem.element.id);
			a.perform();
			a.close();
		}
		else if ((!doc.itemInsertPanel || !doc.itemInsertPanel.isOpen)
				&& (!doc.editorPanel || !doc.editorPanel.isOpen)
				&& (!doc.inlineEdit || !doc.inlineEdit.focus)) {
			if (doc.inEditMode && evn.ctrlKey && evn.shiftKey) {
				if (evn.keyCode == 80) { // Ctrl-Shift-P
					var a = new InsertNoteAction(doc.navLayout.mainItem.getEntityView());
					a.perform();
				}
			}
			else {
				if (!doc.inEditMode && !evn.ctrlKey && !evn.altKey
						&& (((evn.keyCode > 64) && (evn.keyCode < 91)) || // A-Z
						((evn.keyCode > 48) && (evn.keyCode < 57)))) { // 0-9
					var a = new ShowInsertAction(doc.navLayout.mainItem.element.id);
					a.perform();
					a.close();
				}
				else if (doc.inEditMode && doc.selectionSupport.current
				         && !evn.ctrlKey && !evn.altKey && (evn.keyCode == 13)) { // Enter
				  navEntityView(doc.selectionSupport.current.entityView);
				}
			}
		}
		else {
			if (evn.keyCode == 27) { // ESC
				doc.itemInsertPanel && doc.itemInsertPanel.close();
			}
		}
	});
});

EditJob.prototype.onRefresh = function() {
	if (!this.mergeResponse())
	  return false;
	var doc = this.contentPanel.doc;
	doc.navLayout = new NavLayout(doc);
}

function onToggleEditMode() {
	var doc = Doc();
	if (doc.addNoteShortcut) {
		if (doc.inEditMode)
			doc.addNoteShortcut.show();
		else
			doc.addNoteShortcut.hide();
	}
}

function nav(id, uri, evn) {
	if (!document._dropped) {
		// avoid text selection on double click
		try {
			if (this.selection)
				this.selection.empty();
			if (window.getSelection)
				window.getSelection().removeAllRanges();
		}
		catch (ex) {
		}
		if (!evn || (evn.type == "click") || (null == uri) || ("" == uri) || ("#" == uri))
			uri = "nav.html?map=" + id.replace("#", "&item=");
		else if (uri.indexOf("://") < 0)
			uri = BasePath.get() + uri;
		if (evn.shiftKey)
			window.open(uri);
		else
			window.location.href = uri;
	}
}

function navEntityView(ev) {
	var e = ev.dom.element;
	if (document.createEvent) {
		var evt = document.createEvent("MouseEvents");
		evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0,
				null);
		e.dispatchEvent(evt);
	}
	else if (e.fireEvent) {
		e.fireEvent("onclick")
	}
}

NavLayout = function(doc) {
	var tables = doc.doc.body.getElementsByTagName("table");
	var item = tables[0].firstChild.firstChild.childNodes[1].firstChild;
	var left = tables[0].firstChild.firstChild.childNodes[0];
	var right = tables[0].firstChild.firstChild.childNodes[2];

	this.mainItem = Dom(item);
	doc.mainEntityId = this.mainItem.element.id;
	
	// IE does not like a styled tbody
	if (!browser.isIE)
		tables[0].firstChild.style.height = "100%";

	this.rels = new Array();
	for (var i = 1; i < tables.length - 1; ++i) {
		var relBox = Dom(tables[i]);
		var relNodes = relBox.getElementsByClassName("item");
		var rel;
		for (var j = 0; j < relNodes.length; ++j) {
			var r = Dom(relNodes[j]);
			Relation.init(r);
			if (r.element.className.indexOf("rel1") >= 0)
				rel = r;
			this.rels.push(r.getEntityView());
		}
		if (rel)
			new RelationDragSource(relBox, relBox.element, left, right, rel.getEntityView());
	}

	// the label
	this.mainItem.setInlineEdit(function(val) {
		var e = this.dom.getEntityView();
		var a = new UpdateValueAction(e, val, "label");
		a.perform();
		a.close();
	}, "-- label --");

	// the notes
	var content = tables[0].firstChild.childNodes[1].firstChild.firstChild;
	if (1 > content.childNodes.length) {
		var p = document.createElement("p");
		content.appendChild(p);
		doc.addNoteShortcut = Dom(p);
		var ed = doc.addNoteShortcut.setInlineEdit(function(val) {
			var a;
			if (this.dom.element.id) {
				var e = this.dom.getEntityView();
				a = new UpdateValueAction(e, val, ".");
			}
			else {
				if (!val)
					val = "";
				a = new InsertDefaultNoteAction(this, this._entity, val, ".");
			}
			a.perform();
			a.close();
		}, "-- double click to add note --");
		ed._entity = this.mainItem.getEntityView().entity;
		onToggleEditMode();
	}

	if (doc.navSelectionSupport)
	  doc.navSelectionSupport.unselect();
	doc.navSelectionSupport = new NavSelectionSupport(doc, this.rels);
}

NavSelectionSupport = function(doc, rels) {
	this.doc = doc;
	this.doc.navSelectionSupport = this;
	this.relViews = rels;
	this.initialRelView = rels[0];
	this.doc.addEventListener("keydown", this.handleKeyEvent, this);
}

NavSelectionSupport.prototype.handleKeyEvent = function(evn) {
	if (evn.keyCode == 27) { // ESC
		this.unselect();
	}
	else if (!evn.ctrlKey && !Dom(evn.target).isTextEdit()) {
		if (!this.current && (evn.keyCode > 36) && (evn.keyCode < 41))
			this.select(this.initialRelView);
		else if (evn.keyCode == 40) // arrow down
			this.select(this.current.entityView.getDown(this.relViews), false);
		else if (evn.keyCode == 39) // arrow right
			this.select(this.current.entityView.getRight(this.relViews), false);
		else if (evn.keyCode == 38) // arrow up
			this.select(this.current.entityView.getUp(this.relViews), false);
		else if (evn.keyCode == 37) // arrow left
			this.select(this.current.entityView.getLeft(this.relViews), false);
		else if (evn.keyCode == 13) // Enter
			this.process();
		else
			return;
	}
	else
		return;
	return EventListener.cancelEvent(evn);
};

NavSelectionSupport.prototype.select = function(entityView, scrollIntoView) {
	if (!entityView)
		return null;
	if (this.doc.selectionSupport.current && this.doc.selectionSupport.current.active)
		return null;
	if (this.current) {
		if (this.current.entityView == entityView)
			return null;
		this.current.activate(false);
	}
	this.current = new NavSelection(entityView);
	this.current.activate(true);
	return this.current;
};

NavSelectionSupport.prototype.unselect = function() {
	if (!this.current)
		return null;
	this.current.activate(false);
	this.current = null;
};

NavSelectionSupport.prototype.process = function() {
	if (!this.current)
		return null;
	navEntityView(this.current.entityView);
};

function NavSelection(entityView) {
	NavSelection._super.call(this, entityView);
}
Object.extend("NavSelection", "E.Selection");

NavSelection.prototype.activate = function(active, scrollIntoView) {
	NavSelection._super.prototype.activate.call(this, active, scrollIntoView);
	var d = this.entityView.dom;
	if (active) {
		d.addStyleClass("relHover");
		if (d.tooltip) {
			d.tooltip.show();
			var ev = this.entityView;
			d.tooltip.moveTo([ev.v[0] + ev.s[0] / 2, ev.v[1] + ev.s[1] - 2]);
		}
	}
	else {
		d.removeStyleClass("relHover");
		d.tooltip && d.tooltip.hide();
	}
}

function Relation() {
}

Relation.init = function(dom) {
	dom.setTooltip(true);
	dom.addEventListener("dragOver", function(evn) {
		this._draggingOver = true;
		Doc().navSelectionSupport.unselect();
		this.setTooltip(false);
		if (evn.ctrlKey || evn.shiftKey)
			this.addStyleClass("dragOver");
	});
	dom.addEventListener("dragOut", function(evn) {
		this._draggingOver = false;
		this.removeStyleClass("dragOver");
	});
	dom.addEventListener("dropInto", function(evn) {
		this._draggingOver = false;
		this.removeStyleClass("dragOver");
		if (evn.ctrlKey || evn.shiftKey) {
			var e = this.getEntityView();
			var r = evn.dragView.source.rel;
			var a = new MoveIntoAction(e, r.entity, evn.ctrlKey);
			a.perform();
			a.close();
		}
	});
	dom.addEventListener("mouseover", function(evn) {
		if (!this._draggingOver)
			Doc().navSelectionSupport.select(this.getEntityView(), false);
	});
	dom.addEventListener("mouseout", function(evn) {
		Doc().navSelectionSupport.unselect();
	});
}
